/**
 * 
 */
package edu.cornell.cs.lsi.projone.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.BatchPutAttributesRequest;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.ReplaceableItem;
import com.amazonaws.services.simpledb.model.SelectRequest;

import edu.cornell.cs.lsi.projone.common.LSIConstants;
import edu.cornell.cs.lsi.projone.common.LSIException;
import edu.cornell.cs.lsi.projone.model.ServerData;

/**
 * @author poornima
 * 
 */
public class DBManager {

	private final static Log LOGGER = LogFactoryImpl.getLog(DBManager.class);

	private AmazonSimpleDB db = null;

	public DBManager() {
		FileInputStream inputStream;
		try {

			// inputStream = new FileInputStream(
			// "./../../../../../../AwsCredentials.properties");
			LOGGER.info("------------------ "
					+ this.getClass().getResource("/AwsCredentials.properties")
							.getPath());

			String filePath = this.getClass()
					.getResource("/AwsCredentials.properties").getPath();
			inputStream = new FileInputStream(new File(filePath));
			// db = new AmazonSimpleDBClient(new PropertiesCredentials(this
			// .getClass()
			// .getResourceAsStream("AwsCredentials.properties")));

			db = new AmazonSimpleDBClient(
					new PropertiesCredentials(inputStream));
		} catch (FileNotFoundException e1) {
			LOGGER.error("ERROR: File not found");
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			LOGGER.error("ERROR: IO Exception");
		}

	}

	public List<ServerData> getAllServerData() throws LSIException {
		LOGGER.info("getAllServerData(): starts");
		List<ServerData> result = new ArrayList<ServerData>();
		String selectExpression = "select * from `" + LSIConstants.SERVER_DATA
				+ "`";

		SelectRequest selectRequest = new SelectRequest(selectExpression);

		for (Item item : db.select(selectRequest).getItems()) {
			ServerData data = new ServerData();
			for (Attribute attribute : item.getAttributes()) {

				if (LSIConstants.IP_ADDR.equals(attribute.getName())) {
					data.setIpHostName(attribute.getValue());
				}
				if (LSIConstants.PORT.equals(attribute.getName())) {
					data.setPort(Integer.parseInt(attribute.getValue()));
				}
			}
			result.add(data);
		}

		LOGGER.info("getAllServerData(): ends : size of getAllServerData: "
				+ result.size());
		return result;
	}

	public void saveServerData(List<ServerData> serverData) throws LSIException {
		if (serverData == null || serverData.isEmpty()) {
			LOGGER.error("saveServerData(): The incoming server data obj is empty.");
			return;
		}
		deleteAllData();
		List<ReplaceableItem> dataList = new ArrayList<ReplaceableItem>();

		int count = 1;
		for (ServerData sData : serverData) {
			LOGGER.info("=========== DB before save: " + sData.getIpHostName());
			LOGGER.info("=========== DB before save port: " + sData.getPort());
			dataList.add(new ReplaceableItem(String.valueOf(count++))
					.withAttributes(
							new ReplaceableAttribute(LSIConstants.IP_ADDR,
									sData.getIpHostName(), true),
							new ReplaceableAttribute(LSIConstants.PORT, String
									.valueOf(sData.getPort()), true)));
		}
		db.batchPutAttributes(new BatchPutAttributesRequest(
				LSIConstants.SERVER_DATA, dataList));
	}

	public void saveServerData(ServerData serverData) throws LSIException {
		if (serverData == null) {
			return;
		}
		List<ServerData> serverDataList = getAllServerData();
		int count = 0;
		if (serverDataList != null && !serverDataList.isEmpty()) {
			count = serverDataList.size();
		}
		List<ReplaceableItem> dataList = new ArrayList<ReplaceableItem>();
		dataList.add(new ReplaceableItem(String.valueOf(++count))
				.withAttributes(
						new ReplaceableAttribute(LSIConstants.IP_ADDR,
								serverData.getIpHostName(), true),
						new ReplaceableAttribute(LSIConstants.PORT, String
								.valueOf(serverData.getPort()), true)));

		db.batchPutAttributes(new BatchPutAttributesRequest(
				LSIConstants.SERVER_DATA, dataList));

	}

	public void deleteAllData() {
		LOGGER.info("Purging the existing data -------");
		String selectExpression = "select * from `" + LSIConstants.SERVER_DATA
				+ "`";

		SelectRequest selectRequest = new SelectRequest(selectExpression);
		List<Item> itemList = db.select(selectRequest).getItems();
		if (itemList == null || itemList.isEmpty()) {
			return;
		}
		LOGGER.info("Item lists to be purged  -------" + itemList.size());
		for (Item item : itemList) {
			db.deleteAttributes(new DeleteAttributesRequest(
					LSIConstants.SERVER_DATA, item.getName()));
		}
	}

	public static void main(String args[]) throws LSIException, IOException {
		DBManager obj = new DBManager();
		// obj.deleteAllData();
		List<ServerData> serverData = obj.getAllServerData();
		for (ServerData ser : serverData) {
			System.out.println("sss  " + ser.getIpHostName());
			System.out.println("sss  " + ser.getPort());
		}
	}
}